<html>
<head>
  <title>
    Python on the Web
  </title>
  <link id="bespin_base" href="skywriter/"/>
  <script src="skywriter/BespinEmbedded.js"></script>
  <style type="text/css">
      .bespin {
          width: 80%;
          height: 30%;
      }
  </style>

  <!--
        The attached python.js (or python.cc.js) is CPython 2.7.1, licensed under
        the PSF: http://docs.python.org/license.html

        Additional steps to create this demo:

          * Compile with _PyRun_SimpleStringFlags exported in EXPORTED_FUNCTIONS
          * Find the actual name of that function (closure changes it, see .vars), and use it as per the XXX comment below.
  -->

  <script>
    var Module = {
      noInitialRun: true
    };
  </script>
  <script src="python.cc.js"></script>
  <script>
    var orig = Module._PyRun_SimpleStringFlags;
    var RAN_ALREADY;
    QDb = function() { // XXX Have the actual name here! See comment above.
      if(!RAN_ALREADY) {
        RAN_ALREADY = true;
        throw "halting, since this is the first run";
      }
      orig.apply(null, arguments);
    }

    // print function which the Python engine will call
    var lines = [], printed = false;

    function print(text, force) {
      //force = true; // XXX - for debugging
      lines.push(text);
      printed = true;

      if (force) {
        var element = document.getElementById('output');
        element.value = text;
      }
    }

    function execute(text) {
      lines = [];
      printed = false;

      var element = document.getElementById('output');
      if (!element) return; // perhaps during startup

      var ptr = Module.Pointer_make(Module.intArrayFromString(text), 0, 2, 'i8'); // leak!
      try {
        Module._PyRun_SimpleStringFlags(ptr, 0);
      } catch(e) {
        if (e === 'halting, since this is the first run') {
          return;
        }
        element.value = 'JS crash:\n\n' + e + '\n\nPlease let us know about this problem!\n' + element.value;
        return;
      }

      if (printed) {
        element.value = element.value + lines.join('\n') + '\n';
        // scroll down
        var len = element.textLength;
        element.setSelectionRange(len-1, len);
      }
    }

    var editor;

    function doRun() {
      args = ['-S', '-c', 'print 5'];
      try {
        Module.run(args);
      } catch (e) {
        if (e !== 'halting, since this is the first run') {
          throw e;
        }
      }
      setTimeout(function() { 
        if (!bespin.useBespin) setTimeout(arguments.callee, 10);
        bespin.useBespin(document.getElementById('the_input'), { "stealFocus":true, "syntax": "python" }).then(function(env) {
          editor = env.editor;
        });
      }, 10);
    }

  </script>
</head>
<body onload="doRun(); document.getElementById('the_input').focus()">
  <h1>Python on the Web</h1>
  <p>
    This is CPython, the standard <a href="http://www.python.org">Python</a> implementation, compiled from C to
    JavaScript using <a href="http://emscripten.org">Emscripten</a>,
    running in your browser (without any plugins). It is both a tech demo and also a usable tool, for example, to
    assist in teaching people Python by just visiting a website (instead of installing Python locally).
  </p>
  <p>
    Notes:
    <ul>
      <li>Most core language stuff should work, except for importing non-static modules (in other words, <code>import sys</code> will
          work, but other modules won't).</li>
      <li>Please report bugs if you find them!</li>
      <li>The editor is <a href="https://mozillalabs.com/skywriter/">Skywriter</a>.
    </ul>
  </p>
  <hr>
  <!-- Call Python's execution function -->
  <form onsubmit="execute(editor.value); return false">
    <b>Enter some Python</b>:
    <input type="submit" value="execute">
    <div id="the_input">import sys
print 'Hello %s, here are some numbers:' % raw_input('What is your name?'), [2*x for x in range(5)][:4]
print 'This is Python {} on {}'.format(sys.version, sys.platform)
    </div>
  </form>
  <hr>
  <textarea id="output" style="font-family: monospace; width: 80%" rows="8" readonly></textarea>
</body>
</html>
